package by.bsu.wp.latextool.converter;

import java.util.Set;

import org.jgrapht.DirectedGraph;
import org.jgrapht.graph.DefaultEdge;

import by.bsu.wp.latextool.model.NotFullRankSystemProblem;
import by.bsu.wp.latextool.model.ProductFlowEdge;

public class NFRSProblemLatexConverter {

	public String convertToLatex(NotFullRankSystemProblem problem) {
		LatexBuilder lb = new LatexBuilder();
		lb.appendBeginDocumentExt();

		for (Integer product : problem.getProducts()) {

			DirectedGraph<Integer, ProductFlowEdge> productFlowNet = problem.getProductFlowNets().get(product);
			for (Integer vertex : productFlowNet.vertexSet()) {
				lb.appendFormulaMarker();

				boolean isFirts = true;
				for (ProductFlowEdge edge : productFlowNet.outgoingEdgesOf(vertex)) {
					lb.appendFormulaItem(isFirts ? "x" : " + x", vertex.toString() + "," + edge.getTarget().toString(),
							product.toString());
					isFirts = false;
				}

				for (ProductFlowEdge edge : productFlowNet.incomingEdgesOf(vertex)) {
					lb.append(" - ").appendFormulaItem("x", edge.getSource().toString() + "," + vertex.toString(),
							product.toString());
				}

				lb.append(" = ").append(problem.getBalances().get(product).get(vertex).toString());

				lb.appendFormulaMarker();
				lb.appendNewLine();
			}
			lb.appendBigSlip();
		}

		for (int i = 1; i <= problem.getNumberOfBaseEquations(); i++) {
			lb.appendFormulaMarker();

			boolean isFirts = true;
			for (DefaultEdge sourceEdge : problem.getSourceNet().edgeSet()) {
				Integer sourceVertex = problem.getSourceNet().getEdgeSource(sourceEdge);
				Integer targetVertex = problem.getSourceNet().getEdgeTarget(sourceEdge);
				Set<Integer> products = problem.getProductsForEdge(sourceVertex, targetVertex);
				for (Integer product : products) {
					DirectedGraph<Integer, ProductFlowEdge> productFlowNet = problem.getProductFlowNets().get(product);
					ProductFlowEdge productFlowEdge = productFlowNet.getEdge(sourceVertex, targetVertex);
					Integer lambda = productFlowEdge.getLambdaCoefficient(i);
					if ((lambda != null) && (!Integer.valueOf(0).equals(lambda))) {
						if ((lambda > 0) && !isFirts) {
							lb.append(" + ");
						}
						isFirts = false;
						lb.append(lambda.toString()).append(" ");
						lb.appendFormulaItem("x", productFlowEdge.getSource().toString() + ","
								+ productFlowEdge.getTarget().toString(), product.toString());
					}
				}
			}
			lb.append(" = ").append(problem.getBaseEquationTotals().get(i).toString());
			lb.appendFormulaMarker();
			lb.appendNewLine();
			lb.appendBigSlip();
		}
		
//		lb.appendTabularEnvBegin(problem.getSourceNet().edgeSet().size());	
//		lb.appendHorLine().appendFormulaMarker().append("(i, j)").appendFormulaMarker();
//	
//		for (DefaultEdge edge : problem.getSourceNet().edgeSet()) {
//			lb.append("&   \\multicolumn{" + problem.getNumberOFProducts() + "}{|c|}{$(");
//			lb.append(problem.getSourceNet().getEdgeSource(edge).toString());
//			lb.append(",");
//			lb.append(problem.getSourceNet().getEdgeTarget(edge).toString());
//			lb.append(")$}");
//		}
//		lb.appendNewLine().appendHorLine().appendFormulaMarker().append("k").appendFormulaMarker();
//		for (int i = 0; i < problem.getSourceNet().edgeSet().size(); i ++) {
//			for (Integer product : problem.getProducts()) {
//				lb.append("&").append(product.toString());
//			}
//		}
//		
//		lb.appendTabularEnvEnd();

		lb.appendEndDocumentExt();
		return lb.getStringBuilder().toString();
	}
}
